﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Alti.SharePoint.SPDataGenerator.Models;

namespace Alti.SharePoint.SPDataGenerator.Helper
{
    public static class SPDataClassWriter
    {
        private const string contantFormat = "public const string {0} = \"{1}\"; {2}";

        public static string GenerateSPDataClass(List<SPDataList> seletedLists, List<SPDataContentType> selectedContentTypes, string Namespace, bool RenderHiddenFields)
        {
            StringBuilder spDataContent = new StringBuilder();

            spDataContent.AppendFormat("using System;{0}", Environment.NewLine);
            spDataContent.AppendFormat("using System.Collections.Generic;{0}", Environment.NewLine);
            spDataContent.AppendFormat("using System.Linq;{0}", Environment.NewLine);
            spDataContent.AppendFormat("using System.Text;{0}{1}", Environment.NewLine, Environment.NewLine);
            if (!string.IsNullOrEmpty(Namespace))
            {
                spDataContent.AppendFormat("namespace {0}{1}", Namespace, Environment.NewLine);
                spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
            }
            spDataContent.AppendFormat("public static class SPData {0}", Environment.NewLine);
            spDataContent.AppendFormat("{{ {0}", Environment.NewLine);

            DefineContentTypes(spDataContent, selectedContentTypes, RenderHiddenFields);

            DefineLists(spDataContent, seletedLists, RenderHiddenFields);

            spDataContent.AppendFormat("}} {0}", Environment.NewLine);
            if (!string.IsNullOrEmpty(Namespace))
                spDataContent.AppendFormat("}} {0}", Environment.NewLine);

            return spDataContent.ToString();
        }


        private static string DefineContant(string constName, string constValue)
        {
            return string.Format(contantFormat, constName, constValue, Environment.NewLine);
        }

        private static void DefineLists(StringBuilder spDataContent, List<SPDataList> lists, bool RenderHiddenFields)
        {
            spDataContent.AppendFormat("public static class Lists {0}", Environment.NewLine);
            spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
            foreach (SPDataList list in lists)
            {
                if (!string.IsNullOrEmpty(list.Summary))
                    spDataContent.AppendFormat("/// <summary>{0}</summary> {1}", list.Summary, Environment.NewLine);
                spDataContent.AppendFormat("public static class {0} {1}", list.ListName.NormalizeAndPascaliseString(), Environment.NewLine);
                spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
                spDataContent.AppendFormat(DefineContant("Name", list.ListName));
                spDataContent.AppendFormat(DefineContant("ID", list.ListID));
                spDataContent.AppendFormat(DefineContant("ListUrl", list.ListUrl));
                DefineContentTypes(spDataContent, list.ContentTypes, RenderHiddenFields);
                DefineFields(spDataContent, list.Fields, RenderHiddenFields);
                spDataContent.AppendFormat("}} {0}", Environment.NewLine);
            }
            spDataContent.AppendFormat("}} {0}", Environment.NewLine);
        }

        private static void DefineContentTypes(StringBuilder spDataContent, List<SPDataContentType> cts, bool RenderHiddenFields)
        {
            spDataContent.AppendFormat("public static class ContentTypes {0}", Environment.NewLine);
            spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
            foreach (SPDataContentType ct in cts)
            {
                if (!string.IsNullOrEmpty(ct.Summary))
                    spDataContent.AppendFormat("/// <summary>{0}</summary> {1}", ct.Summary, Environment.NewLine);
                spDataContent.AppendFormat("public static class {0} {1}", ct.Name.NormalizeAndPascaliseString(), Environment.NewLine);
                spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
                spDataContent.AppendFormat(DefineContant("Name", ct.Name));
                spDataContent.AppendFormat(DefineContant("ID", ct.ID));
                DefineFields(spDataContent, ct.Fields, RenderHiddenFields);
                spDataContent.AppendFormat("}} {0}", Environment.NewLine);
            }
            spDataContent.AppendFormat("}} {0}", Environment.NewLine);
        }

        private static void DefineFields(StringBuilder spDataContent, List<SPDataField> fields, bool RenderHiddenFields)
        {
            spDataContent.AppendFormat("public static class Fields {0}", Environment.NewLine);
            spDataContent.AppendFormat("{{ {0}", Environment.NewLine);
            foreach (SPDataField field in fields)
            {
                if (!field.Hidden || (field.Hidden && RenderHiddenFields))
                {
                    if (!string.IsNullOrEmpty(field.Summary))
                        spDataContent.AppendFormat("/// <summary>{0}</summary> {1}", field.Summary, Environment.NewLine);
                    spDataContent.AppendFormat(DefineContant(string.Format("{0}", field.PascalLabel), field.InternalName));

                    if (field.FieldValues.Count > 0)
                    {
                        spDataContent.AppendFormat("public static class {0}_FieldValues {1}", field.PascalLabel, Environment.NewLine);
                        spDataContent.AppendFormat("{{ {0}", Environment.NewLine);

                        foreach (KeyValuePair<string, string> aValue in field.FieldValues)
                            spDataContent.AppendFormat(DefineContant(string.Format("{0}", aValue.Key), aValue.Value));

                        spDataContent.AppendFormat("}} {0}", Environment.NewLine);
                    }
                }
            }
            spDataContent.AppendFormat("}} {0}", Environment.NewLine);
        }


    }
}
